﻿using AutoMapper;
using BackData;
using Domain;
using Infratructure;
using MD5Hash;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using RBAC.API.Command.User;
using RBAC.API.DTOs;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace RBAC.API.Handler.User
{
    public class UserLoginHandler : IRequestHandler<UserLoginCommand, ApiResult<LoginDTO>>
    {
        private readonly IRepository<UserModel> userway;
        private readonly ILogger<UserLoginHandler> log;
        private readonly IMapper mapper;
        private readonly IConfiguration configuration;
        private readonly IRepository<RoleModel> roleway;
        private readonly IRepository<UserRoleModel> userroleway;

        public UserLoginHandler(IRepository<UserModel> userway, ILogger<UserLoginHandler> log, IMapper mapper, IConfiguration configuration, IRepository<RoleModel> roleway, IRepository<UserRoleModel> userroleway)
        {
            this.userway = userway;
            this.log = log;
            this.mapper = mapper;
            this.configuration = configuration;
            this.roleway = roleway;
            this.userroleway = userroleway;
        }
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<ApiResult<LoginDTO>> Handle(UserLoginCommand request, CancellationToken cancellationToken)
        {
            ApiResult<LoginDTO> res = new ApiResult<LoginDTO>();
            try
            {
                var value = userway.GetAll().FirstOrDefault(x => x.UserName == request.UserName);
                if (value != null)
                {
                    if (value.UserPwd == request.UserPwd.GetMD5())
                    {
                        //无追踪
                        var roleid = userroleway.GetAll().AsNoTracking()?.FirstOrDefault(x => x.UserId == value.Id)?.RoleId ??1L;
                        var rolename = roleway.GetAll().AsNoTracking()?.FirstOrDefault(x => x.Id == roleid)?.RoleName?? "未分配角色"; 
                        if(string.IsNullOrEmpty(rolename))
                        {
                            res.Message = $"账号{request.UserName}未分配角色";
                            res.Code = StateCode.Fail;
                            return Task.FromResult(res);
                        }
                        LoginDTO dto = new LoginDTO()
                        {
                            UserName = value.UserName,  //账号名称
                            RoleName = rolename,  //角色名称
                            ToKen = CreateTokenString(value.UserName, rolename)
                        };
                        res.Data = dto;
                        res.Message = $"账号{request.UserName}登录成功";
                        res.Code = StateCode.OK;
                    }
                    else
                    {
                        res.Message = $"密码错误";
                        res.Code = StateCode.Fail;
                        return Task.FromResult(res);
                    }
                    return Task.FromResult(res);
                }
                else
                {
                    res.Message = $"账号{request.UserName}不存在";
                    res.Code = StateCode.Fail;
                    return Task.FromResult(res);
                }
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>/// 生成 JWT Token（令牌）/// </summary>/// <returns></returns>
        private string CreateTokenString(string UserName, string RoleName)
        {
            //私钥
            var secretByte = Encoding.UTF8.GetBytes(configuration["PriviteKey"]);
            //载荷
            var claim = new[]
            {
                 new Claim("UserName",UserName),  //账号名称
                 new Claim("RoleName",RoleName)   //角色名称
            };
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: $"{configuration["issuer"]}",
                audience: $"{configuration["audience"]}",
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials,
                claims: claim
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
    }
}
